using System;
using Tao.Sdl;
using Tao.OpenGl;

namespace BC
{
	/// <summary>
	/// Base exceptions for errors eminating from within Zen.
	/// </summary>
	public class ZenException : Exception
	{
		public ZenException( string msg ) : base( msg )
		{
		}
	}
		
	///<summary>
	///A thin but nice, blitzbasic style wrapper over Sdl, combined
	///with 2d-in-3d drawing functions via opengl.
	///</summary>
	public static class Zen
	{
		public static void TestGfx()
		{
			Gl.glBegin( Gl.GL_TRIANGLES );
			
			Gl.glColor3f( 1.0f, 0, 0 );
			Gl.glVertex2f( 0, -64 );
			
			Gl.glColor3f( 0, 1.0f, 0 );
			Gl.glVertex2f( 64, 64 );
			
			Gl.glColor3f( 0, 0, 1.0f );
			Gl.glVertex2f( -64, 64 );
			
			Gl.glEnd();
		}
				
		public static void Cls()
		{
			Gl.glClear( Gl.GL_COLOR_BUFFER_BIT );
		}
		
		public static void Flip()
		{
			Sdl.SDL_Event ev;
						
			while( Sdl.SDL_PollEvent( out ev ) == 1 )
			{
				//process events here
				switch( ev.type )
				{
					case Sdl.SDL_QUIT:
						//later we should route this to an event
						//that the client code can handle...
						//for now just exit
						Environment.Exit(1);
						break;
				}
			}
			
			TestGfx();
			
						
			Sdl.SDL_GL_SwapBuffers();
		}
		
		public static void Graphics( int width, int height, int bpp, bool fullScreen )
		{
			float halfWidth = width / 2.0f, halfHeight = height / 2.0f;
			
			int mode;
			
			if( fullScreen == true )
				mode = Sdl.SDL_FULLSCREEN;
			else
				mode = 0;
			
			//set gl attributes before opening window
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_ALPHA_SIZE, bpp / 4 );
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_RED_SIZE, bpp / 4 );
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_GREEN_SIZE, bpp / 4 );
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_BLUE_SIZE, bpp / 4 );
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_DEPTH_SIZE, 16 );
			Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_DOUBLEBUFFER, 1 );
						
			if( Sdl.SDL_SetVideoMode( width, height, bpp, Sdl.SDL_OPENGL | mode ) == IntPtr.Zero )
				throw new ZenException( "SDL_SetVideoMode() failed." );
			
			
			//now prepare gl for 2d in 3d -------------------------------------
			
			Gl.glMatrixMode( Gl.GL_PROJECTION );
			Gl.glLoadIdentity();
						
			Gl.glOrtho( -halfWidth, halfWidth, halfHeight, -halfHeight, -100, 100 );
			
			Gl.glMatrixMode( Gl.GL_MODELVIEW );
			Gl.glLoadIdentity();
						
			Gl.glClearColor( 0.0f, 0.25f, 0.75f, 0 );
			
			Gl.glDisable( Gl.GL_DEPTH_TEST );
			Gl.glDisable( Gl.GL_LIGHTING );
			Gl.glEnable( Gl.GL_SCISSOR_TEST );
						
			//use clockwise ordering
			Gl.glFrontFace( Gl.GL_CW );

			//cull face
			Gl.glCullFace( Gl.GL_BACK );	
		}
		
		public static void Init()
		{
			if( Sdl.SDL_Init( Sdl.SDL_INIT_VIDEO | Sdl.SDL_INIT_JOYSTICK | Sdl.SDL_INIT_AUDIO ) == -1 )
				throw new ZenException( "SDL_Init() failed." );
				
			//should init sdl_mixer here...	
				
		}
				
		public static void Shutdown()
		{
			Sdl.SDL_Quit();
		}
	}
}